package com.apes.scm.rbac.service;

import com.apes.framework.api.DomainService;
import com.apes.framework.plugin.esb.api.SimpleRequest;
import com.apes.framework.rop.securityManager.SampleSessionManager;
import com.apes.framework.rop.session.SimpleSession;
import com.apes.framework.rop.session.index.SessionIndexItem;
import com.apes.framework.rop.session.index.SessionIndexManager;
import com.apes.framework.util.MapUtil;
import com.apes.oap.session.Session;
import com.apes.scm.masterdata.enumeration.model.Enumeration;
import com.apes.scm.masterdata.frame.model.Branch;
import com.apes.scm.masterdata.frame.repository.BranchRepository;
import com.apes.scm.masterdata.party.model.CompanyEntry;
import com.apes.scm.masterdata.party.model.Party;
import com.apes.scm.masterdata.party.repository.CompanyRepository;
import com.apes.scm.rbac.model.Menu;
import com.apes.scm.rbac.model.Post;
import com.apes.scm.rbac.model.Role;
import com.apes.scm.rbac.model.User;
import com.apes.scm.rbac.repository.PostRepository;
import com.apes.scm.rbac.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.logging.SimpleFormatter;
import java.util.stream.Collectors;

import static java.util.stream.Collectors.*;
import static org.springframework.core.OrderComparator.sort;

/**
 * 功能：在线用户管理
 * @author ZhengZeXian
 * @create 2020年11月5日16:16:21
 */
@Service("onlineUsersService")
public class OnlineUsersService extends DomainService {

    @Autowired
    PostRepository postRepository;
    @Autowired
    CompanyRepository companyRepository;
    @Autowired
    BranchRepository branchRepository;
    @Autowired
    UserRepository userRepository;
    @Autowired
    UserService userService;

//    public Page<Map> findAll(SimpleRequest request){
//        //获取所有的用户会话
//        List<Map> maps = invoke("aut.user.getSessions", request);
//        //根据会话时间排序取最新创建的session会话
//        maps.sort(Comparator.comparing(map -> map.get("created").toString(),Collections.reverseOrder()));
//        //根据用户ID进行去重
//        maps = maps.stream().filter(distinctByKey(b -> b.get("userId"))).collect(Collectors.toList());
//        List<Map> list = new ArrayList<>();
//        //前端数据转换
//        maps.forEach(item ->{
//            String sessionId = item.get("sessionId").toString();
//            SimpleSession session = (SimpleSession) getBean(SampleSessionManager.class).getSession(sessionId);
//            String postName = postRepository.findOne(session.getPostId()).getName();
//            String companyName = companyRepository.findOne(session.getCompanyId()).getName();
//            String branchName = branchRepository.findOne(session.getBranchId()).getName();
//            Map map = new HashMap();
//            map.put("userId",session.getUserId());
//            map.put("userName",session.getUserName());
//            map.put("postName",postName);
//            map.put("companyName",companyName);
//            map.put("branchName",branchName);
//            map.put("ip",session.getIp());
//            map.put("sessionId",sessionId);
//            list.add(map);
//        });
//        Pageable pageable = PageRequest.of(request.get("page"), request.get("size"));
//        PageImpl page = new PageImpl<>(list, pageable, list.size());
//
//        return page;
//    }

    public List<Map> findAll(SimpleRequest request){
        //获取所有的用户会话
        List<Map> maps = invoke("aut.user.getSessions", request);
        //根据会话时间排序取最新创建的session会话
        maps.sort(Comparator.comparing(map -> map.get("created").toString(),Collections.reverseOrder()));
        //根据用户ID进行去重
        maps = maps.stream().filter(distinctByKey(b -> b.get("userId"))).collect(Collectors.toList());
        List<Map> result = new ArrayList<>();
        //前端数据转换
        maps.forEach(item ->{
            String sessionId = item.get("sessionId").toString();
            SimpleSession session = (SimpleSession) getBean(SampleSessionManager.class).getSession(sessionId);
            String postName = postRepository.findOne(session.getPostId()).getName();
            String companyName = companyRepository.findOne(session.getCompanyId()).getName();
            String branchName = branchRepository.findOne(session.getBranchId()).getName();
            User user = userRepository.findOne(Integer.parseInt(session.getUserId()));
            Map map = new HashMap();
            map.put("userId",session.getUserId());
            map.put("userName","( "+ user.getOrigin() + " ) " +session.getUserName());
            map.put("postName",postName);
            map.put("companyName",companyName);
            map.put("companyId",session.getCompanyId());
            map.put("branchId",session.getBranchId());
            map.put("branchName",branchName);
            map.put("ip",session.getIp());
            map.put("create",item.get("created"));
            map.put("sessionId",sessionId);
            map.put("checked",false);
            result.add(map);
        });

        return result;
    }

    public List<Map> getTreePath(SimpleRequest request) {
        List<Map> operations = findAll(request);
        return operations;
    }

    public void logout(SimpleRequest request){
        List<Map> maps = request.get("platformSystemOptList");
        maps.stream().forEach(map -> {
            User user = userRepository.findOne(Integer.valueOf(map.get("userId").toString()));
            if (user != null) {
                userService.killUser(user);
            }
        });
    }

    /**
     *  根据map的key值进行去重
     * @param keyExtractor
     * @param <T>
     * @return
     */
    static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
        Map<Object,Boolean> seen = new ConcurrentHashMap<>(); return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
    }

}
